<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

/**
 * Class BookOrder
 * @package App\Models
 */
class BookOrder extends Model
{
    const CALCULATED = 1;                   // 已计算餐费
    const NOT_CALCULATED = 0;               // 未计算餐费

    const ORDER_STATUS_INIT = 10;           // 订单状态 - 已提交
    const ORDER_STATUS_MAKING = 20;         // 订单状态 - 制作中
    const ORDER_STATUS_COMPLETED = 30;      // 订单状态 - 已完成
    const ORDER_STATUS_CANCELED = 40;       // 订单状态 - 已取消

    const IS_AUTO = 1;                      // 自动添加的订单
    const NOT_AUTO = 0;                     // 手动添加的订单

    const TYPE_NORMAL = 'normal';           // 正常订单
    const TYPE_ADDITION = 'addition';       // 加餐订单
    const TYPE_OFFICIAL = 'official';       // 公务订单
    const TYPE_CHILDREN = 'children';       // 子女订单

    const REVIEWING = 10;                   // 审核中
    const REVIEWED = 20;                    // 通过审核
    const NOT_REVIEWED = 30;                // 未通过审核

    protected $fillable = [
        'user_id',
        'book_rule_id',
        'school_id',
        'eat_name',
        'eat_phone',
        'is_auto',
        'type',
        'children_id'
    ];

    /**
     * @return mixed|null
     */
    public function getStatusLabelAttribute(){
        $statusLabel = [
            self::ORDER_STATUS_INIT => '已提交',
            self::ORDER_STATUS_MAKING => '制作中',
            self::ORDER_STATUS_COMPLETED => '已完成',
            self::ORDER_STATUS_CANCELED => '已取消',
        ];
        return $statusLabel[$this->status] ?? null;
    }

    /**
     * @return mixed|null
     */
    public function getTypeLabelAttribute()
    {
        $typeLabel = [
            self::TYPE_NORMAL => '正常订单',
            self::TYPE_ADDITION => '加餐订单',
            self::TYPE_OFFICIAL => '公务订单',
            self::TYPE_CHILDREN => '子女订单'
        ];
        return $typeLabel[$this->type] ?? null;
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeBesideOfficialOrder($query)
    {
        return $query->whereIn('type', [
            self::TYPE_NORMAL,
            self::TYPE_ADDITION,
            self::TYPE_CHILDREN
        ]);
    }

    /**
     * @param $query
     * @param $status
     * @return mixed
     */
    public function scopeStatusIs($query, $status)
    {
        return $query->when($status, function($query) use ($status){
            $query->where('status',$status);
        });
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsNormalOrChildren($query)
    {
        return $query->whereIn('type', [
            self::TYPE_NORMAL,
            self::TYPE_CHILDREN
        ]);
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsNormal($query) {
        return $query->where("type",self::TYPE_NORMAL);
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsAddition($query){
        return $query->where("type",self::TYPE_ADDITION);
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsOfficial($query)
    {
        return $query->where('type', self::TYPE_OFFICIAL);
    }

    /**
     * @param $query
     * @return mixed
     * 可参与结算的订单type
     */
    public function scopeCanSettle($query)
    {
        return $query->where('type', '<>', self::TYPE_OFFICIAL);
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsCalculated($query){
        return $query->where('is_calculated',self::CALCULATED);
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsBreakfast($query){
        return $query->whereHas("rule",function($query){
           $query->isBreakfast();
        });
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsLunch($query){
        return $query->whereHas("rule",function($query){
            $query->isLunch();
        });
    }
    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsDinner($query){
        return $query->whereHas("rule",function($query){
            $query->isDinner();
        });

    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsInit($query)
    {
        return $query->where('status', '=', self::ORDER_STATUS_INIT);
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsMaking($query)
    {
        return $query->where('status', '=', self::ORDER_STATUS_MAKING);
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsCompleted($query)
    {
        return $query->where('status', '=', self::ORDER_STATUS_COMPLETED);
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsCanceled($query)
    {
        return $query->where('status', '=', self::ORDER_STATUS_CANCELED);
    }

    /**
     * @param $query
     * @return mixed
     */
    public function scopeIsNotCanceled($query)
    {
        return $query->where('status', '<>', self::ORDER_STATUS_CANCELED);
    }

    /**
     * @param $query
     * @param User|null $user
     * @return mixed
     */
    public function scopeBelongToUser($query ,User $user = null){
        if (is_null($user)){
            $user = \Auth::user();
        }
        return $query->where('user_id', $user->id);
    }

    /**
     * @param $query
     * @param $orderType
     * @return mixed
     */
    public function scopeTypeIs($query, $orderType)
    {
        $query->when($orderType, function ($query) use ($orderType) {
            $query->where('type', $orderType);
        });
    }

    /**
     * @param $query
     * @param $review
     */
    public function scopeReviewIs($query, $review)
    {
        $query->when($review, function ($query) use ($review) {
            $query->whereHas('review', function ($query) use ($review) {
                $query->where('status', $review);
            });
        });
    }

    public function scopeEatTypeIs($query, $eatType)
    {
        $query->when($eatType, function ($query) use ($eatType) {
            $query->whereHas('rule', function ($query) use ($eatType) {
                $query->where('eat_type', $eatType);
            });
        });
    }

    public function scopeEatDateIs($query, $eatDate)
    {
        $query->when($eatDate, function ($query) use ($eatDate) {
            $query->whereHas('rule', function ($query) use ($eatDate) {
                $query->where('eat_date', $eatDate);
            });
        });
    }

    public function scopeEatNameLike($query, $eatName)
    {
        $query->when($eatName, function ($query) use ($eatName) {
            $query->where('eat_name', 'like', $eatName . '%');
        });
    }

    public function scopeEatPhoneIs($query, $eatPhone)
    {
        $query->when($eatPhone, function ($query) use ($eatPhone) {
            $query->where('eat_phone', $eatPhone);
        });
    }

    public function scopeCalculatedIs($query, $isCalculated)
    {
        $query->when(!is_null($isCalculated), function ($query) use ($isCalculated) {
            $query->where('is_calculated', $isCalculated);
        });
    }

    public function scopePriceRuleIs($query, $priceRule)
    {
        $query->when($priceRule, function ($query) use ($priceRule) {
            $query->where('price_rule', $priceRule);
        });
    }

    /**
     * @param $query
     * @param $status
     */
    public function scopeSelectStatus($query, $status)
    {
        if ($status == self::ORDER_STATUS_INIT) {
            $query->isInit();
        } elseif ($status == self::ORDER_STATUS_MAKING) {
            $query->isMaking();
        } elseif ($status == self::ORDER_STATUS_COMPLETED) {
            $query->isCompleted();
        } elseif ($status == self::ORDER_STATUS_CANCELED) {
            $query->isCanceled();
        }
    }

    /**
     * @return mixed
     */
    public function getSchoolNameAttribute()
    {
        if (\Auth::guard('school')->check()) {
            return School::findOrFail(\Auth::user()->school_id)->name;
        } else {
            return School::findOrFail($this->school_id)->name;
        }
    }

    /**
     * @return mixed
     */
    public function getEatDateAttribute()
    {
        return $this->rule->eat_date;
    }

    /**
     * @return string
     */
    public function getEatTypeAttribute()
    {
        if ($this->rule->eat_type === BookRule::EAT_TYPE_BREAKFAST) {
            return '早餐';
        } elseif ($this->rule->eat_type === BookRule::EAT_TYPE_LUNCH) {
            return '午餐';
        } elseif ($this->rule->eat_type === BookRule::EAT_TYPE_DINNER) {
            return '晚餐';
        }
    }

    /**
     * @return string
     */
    public function getIsCalculateAttribute()
    {
        if ($this->is_calculated === self::CALCULATED) {
            return '已结算';
        } elseif ($this->is_calculated === self::NOT_CALCULATED) {
            return '未结算';
        }
        return '';
    }

    /**
     * @return string
     */
    public function getRuleNameAttribute()
    {
        if ($this->price_rule === UserRole::FIXED_MEAL_MARK) {
            return '固定餐标';
        } elseif ($this->price_rule === UserRole::CHARGING_MEAL_MARK) {
            return '计算餐标';
        } elseif ($this->price_rule === UserRole::ADDITION_MEAL_MARK) {
            return '计全额';
        }
        return '';
    }

    /**
     * @return string
     */
    public function getReviewLabelAttribute()
    {
        if ($this->status === self::ORDER_STATUS_CANCELED){
            return '已取消';
        }
        if ($this->review['status'] === self::REVIEWING) {
            return '审核中';
        } elseif ($this->review['status'] === self::REVIEWED) {
            return '审核通过';
        } elseif ($this->review['status'] === self::NOT_REVIEWED) {
            return '审核未通过';
        }
        return '';
    }

    /**
     * @return mixed
     */
    public function getReviewMessageAttribute()
    {
        return $this->review['message'];
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function user()
    {
        return $this->belongsTo(User::class, 'user_id');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function rule()
    {
        return $this->belongsTo(BookRule::class,'book_rule_id');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function school()
    {
        return $this->belongsTo(School::class);
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
     */
    public function review()
    {
        return $this->hasOne(BookOrderReview::class, 'order_id');
    }

    /**
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
     */
    public function children()
    {
        return $this->belongsTo(Child::class);
    }

    /**
     * @return bool
     * 取消订单
     */
    public function cancel()
    {
        if ($this->status == self::ORDER_STATUS_INIT && $this->is_calculated == self::NOT_CALCULATED) {
            $this->status = self::ORDER_STATUS_CANCELED;
            $this->canceled_at = now()->format("Y-m-d H:i:s");
            return $this->save();
        }
        return false;
    }

    /**
     * @return $this|bool
     */
    public function making()
    {
        if($this->status === self::ORDER_STATUS_INIT){
            $this->status = self::ORDER_STATUS_MAKING;
            $this->making_at = now()->format("Y-m-d H:i:s");
            if ($this->save()) {
                return $this;
            }
        }
        return false;
    }

    /**
     * @return $this|bool
     */
    public function finished()
    {
        if($this->status === self::ORDER_STATUS_MAKING){
            $this->status = self::ORDER_STATUS_COMPLETED;
            $this->finished_at = now()->format("Y-m-d H:i:s");
            if ($this->save()) {
                return $this;
            }
        }
        return false;
    }

    /**
     * @return $this|bool
     * 后台取消订单
     */
    public function backendCancel()
    {
        if ($this->status != self::ORDER_STATUS_CANCELED && $this->is_calculated == self::NOT_CALCULATED) {
            $this->status = self::ORDER_STATUS_CANCELED;
            $this->canceled_at = now()->format("Y-m-d H:i:s");
            if ($this->save()) {
                return $this;
            }
        }
        return false;
    }
}

